package com.geek.water.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geek.water.entity.Role;
import com.geek.water.entity.User;
import com.geek.water.entity.Menu;
import com.geek.water.entity.Customer;
import com.geek.water.mapper.UserMapper;
import com.geek.water.mapper.UserPermissionMapper;
import com.geek.water.service.RoleService;
import com.geek.water.service.UserRoleService;
import com.geek.water.service.UserService;
import com.geek.water.service.CustomerService;
import com.geek.water.vo.UserLoginQueryVO;
import com.geek.water.vo.UserPageQueryVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author chenmin
 * @desc 用户服务实现类
 * @date 2025/7/24
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private UserPermissionMapper userPermissionMapper;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;


    @Transactional(readOnly = true)
    @Override
    public User login(UserLoginQueryVO vo) {
        if (ObjectUtils.isEmpty(vo)) {
            return null;
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.hasLength(vo.getUsername()), User::getUsername, vo.getUsername())
                .eq(StringUtils.hasLength(vo.getPassword()), User::getPassword, vo.getPassword())
                .eq(User::getStatus, "enabled"); // 只允许启用状态的用户登录
        User user = baseMapper.selectOne(queryWrapper);
        return user;
    }

    @Override
    public Page<User> findPage(UserPageQueryVO userPageQueryVO) {
        // 创建分页对象
        Page<User> page = new Page<>(userPageQueryVO.getCurrentPage(), userPageQueryVO.getPageSize());

        // 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        // 综合搜索条件
        if (StringUtils.hasLength(userPageQueryVO.getQueryString())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(User::getUsername, userPageQueryVO.getQueryString())
                    .or()
                    .like(User::getMobile, userPageQueryVO.getQueryString())
                    .or()
                    .like(User::getEmail, userPageQueryVO.getQueryString())
            );
        }

        // 状态筛选
        if (StringUtils.hasLength(userPageQueryVO.getStatus())) {
            queryWrapper.eq(User::getStatus, userPageQueryVO.getStatus());
        }

        // 客户ID筛选
        if (userPageQueryVO.getCustomerId() != null) {
            queryWrapper.eq(User::getCustomerId, userPageQueryVO.getCustomerId());
        }

        // 创建时间范围筛选
        if (userPageQueryVO.getCreatedAtStart() != null) {
            queryWrapper.ge(User::getCreatedAt, userPageQueryVO.getCreatedAtStart());
        }
        if (userPageQueryVO.getCreatedAtEnd() != null) {
            queryWrapper.le(User::getCreatedAt, userPageQueryVO.getCreatedAtEnd());
        }

        // 排序
        if (StringUtils.hasLength(userPageQueryVO.getSortField())) {
            boolean isAsc = "asc".equalsIgnoreCase(userPageQueryVO.getSortOrder());
            switch (userPageQueryVO.getSortField()) {
                case "createdAt":
                    queryWrapper.orderBy(true, isAsc, User::getCreatedAt);
                    break;
                case "lastLoginTime":
                    queryWrapper.orderBy(true, isAsc, User::getLastLoginTime);
                    break;
                case "username":
                    queryWrapper.orderBy(true, isAsc, User::getUsername);
                    break;
                default:
                    queryWrapper.orderByDesc(User::getCreatedAt);
            }
        } else {
            queryWrapper.orderByDesc(User::getCreatedAt);
        }

        return baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public Page<User> findPageWithRoles(UserPageQueryVO userPageQueryVO) {
        Page<User> page = findPage(userPageQueryVO);

        // 为每个用户加载角色信息和客户信息
        if (page.getRecords() != null && !page.getRecords().isEmpty()) {
            page.getRecords().forEach(user -> {
                // 加载角色信息
                List<Long> roleIds = userRoleService.getRoleIdsByUserId(user.getId());
                if (roleIds != null && !roleIds.isEmpty()) {
                    List<Role> roles = roleService.listByIds(roleIds);
                    user.setRoles(roles);
                } else {
                    log.debug("用户{}没有分配角色", user.getId());
                }

                // 加载客户信息
                if (user.getCustomerId() != null) {
                    try {
                        Customer customer = customerService.getById(user.getCustomerId());
                        if (customer != null) {
                            user.setCustomerName(customer.getName());
                        }
                    } catch (Exception e) {
                        log.warn("加载用户{}的客户信息失败: {}", user.getId(), e.getMessage());
                    }
                }
            });
        }

        return page;
    }

    @Override
    public User findByUsername(String username) {
        if (!StringUtils.hasLength(username)) {
            return null;
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public User getUserWithRoles(Long id) {
        User user = getById(id);
        if (user != null) {
            // 加载角色信息
            List<Long> roleIds = userRoleService.getRoleIdsByUserId(id);
            if (roleIds != null && !roleIds.isEmpty()) {
                List<Role> roles = roleService.listByIds(roleIds);
                user.setRoles(roles);
            } else {
                log.debug("用户{}没有分配角色", id);
            }

            // 加载客户信息
            if (user.getCustomerId() != null) {
                try {
                    Customer customer = customerService.getById(user.getCustomerId());
                    if (customer != null) {
                        user.setCustomerName(customer.getName());
                    }
                } catch (Exception e) {
                    log.warn("加载用户{}的客户信息失败: {}", id, e.getMessage());
                }
            }
        }
        return user;
    }

    @Override
    public boolean updateUserStatus(Long id, String status) {
        if (id == null || !StringUtils.hasLength(status)) {
            return false;
        }
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, id)
                .set(User::getStatus, status)
                .set(User::getUpdatedAt, LocalDateTime.now());
        return baseMapper.update(null, updateWrapper) > 0;
    }

    @Override
    public boolean resetPassword(Long id, String newPassword) {
        if (id == null || !StringUtils.hasLength(newPassword)) {
            return false;
        }
        // 重置密码时也需要编码
        String encodedPassword = passwordEncoder.encode(newPassword);
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, id)
                .set(User::getPassword, encodedPassword)
                .set(User::getUpdatedAt, LocalDateTime.now());
        return baseMapper.update(null, updateWrapper) > 0;
    }

    @Override
    public boolean updatePassword(Long id, String newPassword) {
        if (id == null || !StringUtils.hasLength(newPassword)) {
            return false;
        }
        // 更新密码时自动编码
        String encodedPassword = passwordEncoder.encode(newPassword);
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, id)
                .set(User::getPassword, encodedPassword)
                .set(User::getUpdatedAt, LocalDateTime.now());
        return baseMapper.update(null, updateWrapper) > 0;
    }

    @Override
    public boolean updateLastLoginTime(Long id) {
        if (id == null) {
            return false;
        }
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, id)
                .set(User::getLastLoginTime, LocalDateTime.now());
        return baseMapper.update(null, updateWrapper) > 0;
    }

    @Override
    @Transactional(readOnly = true)
    public List<Integer> getUserPermissionIds(Long userId) {
        if (userId == null) {
            return Collections.emptyList();
        }
        try {
            List<Integer> allPermissionIds = new ArrayList<>();

            // 1. 查询用户通过基础角色获得的权限（不包括专属权限角色）
            List<Integer> baseRolePermissionIds = userPermissionMapper.selectUserBaseRolePermissionIds(userId);
            if (baseRolePermissionIds != null && !baseRolePermissionIds.isEmpty()) {
                allPermissionIds.addAll(baseRolePermissionIds);
                log.debug("用户{}通过基础角色获得权限: {}", userId, baseRolePermissionIds.size());
            }

            // 2. 查询用户通过专属权限角色获得的权限（这些是用户自定义的权限）
            List<Integer> customPermissionIds = userPermissionMapper.selectUserCustomPermissionIds(userId);
            if (customPermissionIds != null && !customPermissionIds.isEmpty()) {
                allPermissionIds.addAll(customPermissionIds);
                log.debug("用户{}通过专属角色获得权限: {}", userId, customPermissionIds.size());
            }

            // 3. 如果没有权限，尝试查询菜单权限
            if (allPermissionIds.isEmpty()) {
                List<Integer> menuIds = userPermissionMapper.selectUserMenuIds(userId);
                if (menuIds != null && !menuIds.isEmpty()) {
                    allPermissionIds.addAll(menuIds);
                    log.debug("用户{}通过菜单获得权限: {}", userId, menuIds.size());
                }
            }

            // 去重
            List<Integer> uniquePermissionIds = allPermissionIds.stream()
                    .distinct()
                    .collect(Collectors.toList());

            log.info("查询用户权限ID成功，用户ID: {}, 基础权限: {}, 自定义权限: {}, 总计: {}",
                    userId,
                    baseRolePermissionIds != null ? baseRolePermissionIds.size() : 0,
                    customPermissionIds != null ? customPermissionIds.size() : 0,
                    uniquePermissionIds.size());

            return uniquePermissionIds;
        } catch (Exception e) {
            log.error("查询用户权限ID失败，用户ID: {}", userId, e);
            return Collections.emptyList();
        }
    }

    @Override
    @Transactional(readOnly = true)
    public List<Menu> getUserPermissions(Long userId) {
        if (userId == null) {
            return Collections.emptyList();
        }
        try {
            List<Menu> permissions = userPermissionMapper.selectUserMenus(userId);
            log.info("查询用户权限详情成功，用户ID: {}, 权限数量: {}", userId, permissions.size());
            return permissions != null ? permissions : Collections.emptyList();
        } catch (Exception e) {
            log.error("查询用户权限详情失败，用户ID: {}", userId, e);
            return Collections.emptyList();
        }
    }

    @Override
    @Transactional
    public boolean saveUserPermissions(Long userId, List<Integer> permissionIds) {
        if (userId == null || permissionIds == null) {
            return false;
        }
        try {
            // 新的权限管理方案：直接更新用户的权限，不依赖角色
            // 1. 获取用户当前的所有角色
            List<Long> userRoleIds = userRoleService.getRoleIdsByUserId(userId);
            if (userRoleIds.isEmpty()) {
                log.warn("用户{}没有角色，无法分配权限", userId);
                return false;
            }

            // 2. 检查用户是否已有专属权限角色
            String userSpecificRoleName = "USER_" + userId + "_CUSTOM";
            Role customRole = roleService.getOne(new LambdaQueryWrapper<Role>()
                    .eq(Role::getName, userSpecificRoleName));

            Long customRoleId;
            if (customRole == null) {
                // 创建专属权限角色
                customRole = new Role();
                customRole.setName(userSpecificRoleName);
                roleService.save(customRole);
                customRoleId = customRole.getId();

                // 将专属角色分配给用户
                userRoleService.assignRolesToUser(userId, Arrays.asList(customRoleId));
                log.info("为用户{}创建专属权限角色，角色ID: {}", userId, customRoleId);
            } else {
                customRoleId = customRole.getId();
                log.info("用户{}已有专属权限角色，角色ID: {}", userId, customRoleId);
            }

            // 3. 更新专属角色的权限（这些是用户自定义的权限）
            int deletedCount = userPermissionMapper.deleteRolePermissions(customRoleId);
            log.info("删除角色{}原有权限，影响行数: {}", customRoleId, deletedCount);

            if (!permissionIds.isEmpty()) {
                int insertedCount = userPermissionMapper.insertRolePermissions(customRoleId, permissionIds);
                log.info("为角色{}插入新权限，影响行数: {}", customRoleId, insertedCount);
            }

            log.info("保存用户自定义权限成功，用户ID: {}, 专属角色ID: {}, 权限数量: {}",
                    userId, customRoleId, permissionIds.size());
            return true;
        } catch (Exception e) {
            log.error("保存用户权限失败，用户ID: {}", userId, e);
            return false;
        }
    }


    @Override
    @Transactional(readOnly = true)
    public User findByMobile(String mobile) {
        if (!StringUtils.hasLength(mobile)) {
            return null;
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getMobile, mobile)
                .eq(User::getStatus, "enabled"); // 只查询启用状态的用户
        User user = baseMapper.selectOne(queryWrapper);
        log.info("根据手机号查询用户，手机号: {}, 结果: {}", mobile, user != null ? "用户存在" : "用户不存在");
        return user;
    }

    /**
     * 重写save方法，在保存用户前自动编码密码
     */
    @Override
    public boolean save(User entity) {
        // 在保存用户前，自动编码密码
        if (StringUtils.hasLength(entity.getPassword())) {
            String encodedPassword = passwordEncoder.encode(entity.getPassword());
            entity.setPassword(encodedPassword);
            log.info("用户密码已自动编码，用户名: {}", entity.getUsername());
        }
        return super.save(entity);
    }

    /**
     * 重写updateById方法，在更新用户密码时自动编码
     */
    @Override
    public boolean updateById(User entity) {
        // 如果更新了密码，需要重新编码
        if (StringUtils.hasLength(entity.getPassword())) {
            // 检查密码是否已经编码过（BCrypt编码的密码以$2a$开头）
            if (!entity.getPassword().startsWith("$2a$")) {
                String encodedPassword = passwordEncoder.encode(entity.getPassword());
                entity.setPassword(encodedPassword);
                log.info("用户密码已自动编码，用户ID: {}", entity.getId());
            }
        }
        return super.updateById(entity);
    }

}
